//封装http请求
import axios from 'axios'
import { history } from './history'
import { getToken, removeToken, setToken } from './token'
// 通过 process.env.REACT_APP_URL 就可以读取到配置文件中，配置的接口路径了
const baseURL = process.env.REACT_APP_URL
// 创建axios实例
const http = axios.create({
  // 请求行
  baseURL,
  // 请求延时
  timeout: 5000,
})

//鉴权   俗话：认证信息是否相符
// 请求拦截器  config===>输入的账户登录请求信息（对象）
// startsWith  以...开头
http.interceptors.request.use(config => {
  // 非登录接口，再添加 token     认证信息的接口
  if (!config.url.startsWith('/authorizations')) {
    const { token } = getToken()
    // 判断是否有 token 如果有，再添加请求头,注意这里是在个人信息页面才能看到Authorization的请求
    if (token) {
      config.headers.Authorization = `Bearer ${token}`
      // console.log(config)
    }
  }
  // 用户信息
  return config
})

//响应拦截器
http.interceptors.response.use(
  response => response,
  async error => {
    try {
      //判断token是否失效
      if (error.response.status === 401) {
        // 换取最新的 token
        const { refresh_token } = getToken()
        // 判断本地存储中是否有 refresh_token
        if (!refresh_token) {
          // 跳转到登录页面
          return history.push('/login')
        }
        // 使用 axios 来发送请求
        // 为什么要使用 axios ？
        // 因为如果使用 http，此处我们单独设置的 Authorization 就会被 http 请求拦截器中配置的 Authorization 覆盖！！！
        // 注意：put 方法的第二个参数是要传递的数据，此处没有数据，所以，传入 null
        //      第三个参数才是 配置
        const res = await axios.put(`${baseURL}/authorizations`, null, {
          header: {
            Authorization: `Bearer ${refresh_token}`,
          },
        })
        const { token } = res.data.data
        setToken({ token, refresh_token })
        // error.config 获取的是出错的请求的配置信息，此处，就是 获取用户个人信息 时的配置信息
        // 注意：此处需要 return ，将来在 获取用户个人信息时，才能拿到结果！
        // console.log(error.config);
        return http(error.config)
      }
    } catch (e) {
      // 如果代码执行到此处，说明 refresh_token 过期了
      // 此时，跳转到登录页面

      // 1 删除本地 token
      removeToken()
      // 2 跳转到登录页面
      history.push('/login')
    }
    // - 四个静态方法
    // - Promise.all() 所有的请求都执行完毕,才会走 下一步
    // - Promimse.race() 只要有一个先执行完毕,就会走下一步
    // - Promise.resolve()  只有成功的时候
    // - Promise.reject()    只有失败的时候
    // 返回失败的结果
    return Promise.reject(error)
  }
)
export { http }
